package com.net.client;

import com.net.common.entity.Message;
import com.net.common.util.CloseableUtils;
import com.net.common.util.ValidatorUtils;
import com.net.common.util.MessageSerializableUtils;
import com.net.common.util.ThreadPoolFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.concurrent.TimeUnit;

import static com.net.client.Client.clientProperties;


/**
 * 服务端消息监听器
 *
 * @author hjh
 */
public class ListenerMessage implements Listener {

    private static final Logger log = LoggerFactory.getLogger(ListenerMessage.class);
    /**
     * 客户端socket
     */
    private final Socket clientSocket;

    public ListenerMessage(Socket socket) {
        this.clientSocket = socket;
    }

    /**
     * 监听服务端消息
     */
    @Override
    public void messageListener() {
        while (!clientSocket.isClosed() && clientSocket.isConnected()) {
            try {
                // 监听服务端消息
                Message message = MessageSerializableUtils.listenerSerializableMessage(clientSocket.getInputStream());

                // 监听到消息就进行转发
                ThreadPoolFactory.execute(new ForwardMessageRunnable(clientProperties.getLocalIp(), clientProperties.getLocalPort(), message, clientSocket));
            } catch (SocketTimeoutException timeoutException) {
                log.error("与服务端[{}]长时间未通信连接自动断开", clientProperties.getServerIp() + ":" + clientProperties.getServerPort());
                break;
            } catch (Exception e) {
                log.error("与服务端[{}:{}]断开连接,原因:{}", clientProperties.getServerIp(), clientProperties.getServerPort(), e.getMessage());
                break;
            }
        }
        // 关闭资源
        CloseableUtils.close(clientSocket);
    }

    @Override
    public void scheduleConnectionListener() {
        ThreadPoolFactory.scheduleAtFixedRate(() -> {
            boolean validate = ValidatorUtils.validate(clientProperties.getLocalIp(), clientProperties.getLocalPort());
            if (validate) {
                return;
            }
            log.info("内网服务{}:{}不可用断开连接！", clientProperties.getLocalIp(), clientProperties.getLocalPort());
            CloseableUtils.close(clientSocket);
        }, 3, 60, TimeUnit.SECONDS);
    }
}
